package org.semanticflash.rdf
{
	
	import com.bigflexlib.ds.container.bag.IOWBag;
	import com.bigflexlib.ds.container.bag.impl.owBag;
	import com.bigflexlib.ds.container.zet.IOSet;
	import com.bigflexlib.ds.container.zet.IOWSet;
	import com.bigflexlib.ds.container.zet.impl.owSet;
	import com.bigflexlib.ds.op.ContainerFieldProjectionOp;
	import com.bigflexlib.ds.op.ContainerToListOp;
	import com.bigflexlib.ds.op.ContainerToSetOp;
	import com.bigflexlib.utils.IOperator;
	
	import org.semanticflash.rdf.triple.IRDFIndexedTripleProvider;
	import org.semanticflash.rdf.triple.RDFTriple;
	import org.semanticflash.rdf.utils.GSPOQueryBase;

	/**
	 * 
	 * The simplest rdf query ever!
	 * 
	 * @author aldo.bucchi@gmail.com
	 * 
	 */
	public class Q extends GSPOQueryBase
	{
		
		public function get tripleProvider( ):IRDFIndexedTripleProvider
		{
			// TODO: we should look up the service using the displaylist
			return RDFService.i.graph;
		}
		
		private var ops:Array = [];
				
		private function disposeOps( ):void
		{
			for each ( var op:IOperator in ops )
				op.dispose( );
			ops = [];
		}
		
		public function refresh( ):void
		{
			queryChanged();		
		}
			
		override protected function queryChanged():void
		{
			disposeOps( ); // clear previous operators
			var tripleMask:RDFTriple = RDFTriple.instance( s, p, o );
			if ( !hasRequiredValues() )
			{
				_list.removeAll( );
				return;
			}
			var triples:IOSet = tripleProvider.getTriples( tripleMask );			
			var allTerms:IOWBag = owBag( );
			var distinctTerms:IOWSet = owSet( );
			ops.push( new ContainerFieldProjectionOp( triples, allTerms, term ) );		

			if ( distinct )
				ops.push( new ContainerToSetOp( allTerms, distinctTerms ) );	
			ops.push( new ContainerToListOp( distinct ? distinctTerms : allTerms , _list ) );
			
		}
	}
}